package hebClustering.nlp;


import hebClustering.documentTypes.Document;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
 * 	A corpus that holds a set of all the documents, and all of their tokens.
 *	Implements the singleton design pattern.
 */
public class Corpus {
	
	private static int id = 0;
	private static Corpus corpusInstance=null;

	Set<Document> documentSet;
	private HashMap<String,Token> tokens;
	
	/**
	 * A private constructor that creates an new empty corpus. 
	 */
	private Corpus(){
		tokens = new HashMap<String,Token>();
		documentSet = new HashSet<Document>();
	}
	
	/**
	 * Returns the only instance of the corpus.
	 * 
	 * @return The instance of the corpus.
	 */
	static public Corpus getCorpus(){
		if(corpusInstance==null)
			corpusInstance = new Corpus();
		
		return corpusInstance;
	}
	
	/**
	 * Add a new token to the corpus.
	 * 
	 * @param text - the new token.
	 */
	public void addToken(String text){
		if(!contains(text)){
			Token tok = new Token(text,Corpus.id++);
			tokens.put(text,tok);
		}
		else {
			Token token = tokens.get(text);
			token.addAppearence();
		}
	}
	
	/**
	 * Add a collection of tokens to the corpus.
	 * 
	 * @param textCollection - A collection of tokens.
	 */
	public void addTokens(Collection<String> textCollection){
		for(String text : textCollection)
			addToken(text);
	}
	
	/**
	 * Checks whether the corpus contains a token.
	 * 
	 * @param text - The token.
	 * 
	 * @return true if the corpus contains the given token.
	 */
	public boolean contains(String text){
		return tokens.containsKey(text);
	}
	
	/**
	 * Returns a token from the corpus, given it's text.
	 * 
	 * @param text - The text of the token.
	 * 
	 * @return The token.
	 */
	public Token getToken(String text) {
		return tokens.get(text);
	}
	
	/**
	 * Returns the number of tokens the corpus currently hold.
	 * 
	 * @return Number of tokens
	 */
	public int getNumOfTokens(){
		return tokens.size();
	}

	/**
	 * Returns the number of documents the corpus currently hold.
	 * 
	 * @return Number of documents.
	 */
	public int getNumDocs() {
		return documentSet.size();
	}
	
	/**
	 * Returns a token from the corpus, given it's index.
	 * 
	 * @param i - The index of the token.
	 * 
	 * @return The token.
	 */
	public String getTokenByIndex(int i){
		for (Token t : tokens.values()){
			if (t.getId() == i)
				return t.getText();
		}
		return null;
	}

	/**
	 * Add a collection of documents to the corpus.
	 * 
	 * @param documentCollection
	 */
	public void addDocuments(Collection<Document> documentCollection) {
		for(Document doc : documentCollection)
			addDocument(doc);
	}
	
	/**
	 * Add a document to the corpus.
	 * 
	 * @param doc
	 */
	public void addDocument(Document doc) {
		documentSet.add(doc);
		//addTokens(doc.getWordSet());
	}

	public void reset() {
		id = 0;
		tokens = new HashMap<String,Token>();
		documentSet = new HashSet<Document>();
	}
}